﻿using System;
using GeoAPI.Geometries;
using NetTopologySuite.Algorithm.Locate;
using NetTopologySuite.Geometries;

namespace NetTopologySuite.Shape.Random
{
	public class RandomPointsBuilder : GeometricShapeBuilder
	{
		public RandomPointsBuilder() : this(new GeometryFactory())
		{
		}

		public RandomPointsBuilder(IGeometryFactory geomFact) : base(geomFact)
		{
		}

		public void SetExtent(IGeometry mask)
		{
			if (!(mask is IPolygonal))
			{
				throw new ArgumentException("Only polygonal extents are supported");
			}
			this._maskPoly = mask;
			base.Extent = mask.EnvelopeInternal;
			this._extentLocator = new IndexedPointInAreaLocator(mask);
		}

		public override IGeometry GetGeometry()
		{
			Coordinate[] array = new Coordinate[base.NumPoints];
			int i = 0;
			while (i < base.NumPoints)
			{
				Coordinate coordinate = this.CreateRandomCoord(base.Extent);
				if (this._extentLocator == null || this.IsInExtent(coordinate))
				{
					array[i++] = coordinate;
				}
			}
			return this.GeomFactory.CreateMultiPoint(array);
		}

		protected bool IsInExtent(Coordinate p)
		{
			if (this._extentLocator != null)
			{
				return this._extentLocator.Locate(p) != Location.Exterior;
			}
			return base.Extent.Contains(p);
		}

		protected Coordinate CreateRandomCoord(Envelope env)
		{
			double x = env.MinX + env.Width * RandomPointsBuilder.Rnd.NextDouble();
			double y = env.MinY + env.Height * RandomPointsBuilder.Rnd.NextDouble();
			return base.CreateCoord(x, y);
		}

        protected static readonly System.Random Rnd = new System.Random();

		private IGeometry _maskPoly;

		private IPointOnGeometryLocator _extentLocator;
	}
}
